{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "empty_list: list[str] = []\n",
    "all(empty_list)  # False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mixed_list: list[int] = [1, 2, 0, 4, 5]\n",
    "all(mixed_list)  # 0 is falsy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mixed_list: list[int | None] = [1, 2, None, 4, 5]\n",
    "all(mixed_list)  # None is falsy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class IsEven:\n",
    "    def __init__(self, value: int):\n",
    "        self.value = value\n",
    "\n",
    "    def __bool__(self):\n",
    "        return self.value % 2 == 0\n",
    "\n",
    "\n",
    "objects = [IsEven(1), IsEven(2), IsEven(0)]\n",
    "all(objects)  # Output: False (the last object is falsy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class Cart:\n",
    "    def __init__(self, items: list[str]):\n",
    "        self.items = items\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self.items)\n",
    "\n",
    "\n",
    "objects = [Cart(items=[\"a\"]), Cart(items=[\"b\"]), Cart(items=[])]\n",
    "all(objects)  # the last object is falsy due to empty list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class Cart:\n",
    "    def __init__(self, items: list[str]):\n",
    "        self.items = items\n",
    "\n",
    "    def __len__(self):\n",
    "        return len([item for item in self.items if item != \"b\"])\n",
    "\n",
    "    def __bool__(self):\n",
    "        return \"a\" not in self.items\n",
    "\n",
    "\n",
    "objects = [Cart(items=[\"b\"])]\n",
    "all(objects)  # __bool__ seems to have higher priority than __len__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "non_empty_string is True\n",
      "empty_string is True\n"
     ]
    }
   ],
   "source": [
    "non_empty_string = \"hello\"\n",
    "empty_string = \"\"\n",
    "\n",
    "print(f\"non_empty_string is {all(non_empty_string)}\")  # all characters are truthy\n",
    "print(f\"empty_string is {all(empty_string)}\")  # empty iterable"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nested_list: list[list[int]] = [[1, 2], [3, 4], []]\n",
    "all(\n",
    "    nested_list\n",
    ")  # the empty list is falsy in this case, since it does not recursively check the nested lists"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "numbers = (x > 0 for x in range(1, 10))\n",
    "print(all(numbers))  # all elements are > 0\n",
    "\n",
    "gen_with_falsy = (x > 0 for x in range(-5, 5))\n",
    "print(all(gen_with_falsy))  # -5 to -1 are falsy"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
